#include "XLogger.h"
#include <fstream>
using namespace std;
XLogger* XLogger::init()
{
    static XLogger logger;
    return &logger;
}

void XLogger::outPut(std::string text, std::string filename, Level level,string workingFile)
{
    if (level<m_level) {
        return;
    }
    ofstream outfile;
    if (m_device != T_CONSILE) {
        outfile.open(filename, ios::out | ios::app);   // ???????????
    }
    string msg=getMesg(level,text,workingFile);
    if (m_device != T_FILE) {
        cout<< msg;
    }
    if (m_device != T_CONSILE)
    {
        outfile << msg;
        outfile.close();
    }
}

/*void XLogger::outPut(std::string text, FILE* file, Level level, string workingFile)
{
    if (level < m_level) {
        return;
    }
    ofstream outfile(file);
    string output_content = getMesg(level,text,workingFile);
    if (m_device != T_FILE && file!=stdout) {
        cout << output_content;
    }
    if (m_device != T_CONSILE && file != stdout)
    {
        outfile << output_content;
        outfile.close();
    }
};*/

void XLogger::outPut(function<void()> fun, Level level)
{
    if (level < m_level) {
        return;
    }
    fun();
}

void XLogger::outPut(std::function<void (std::string)> fun, string text, string filename, Level level, string workingFile)
{
    if (level < m_level) {
        return;
    }
    ofstream outfile;
    if (m_device != T_CONSILE) {
        outfile.open(filename, ios::out | ios::app);   // ???????????
    }
    string msg=getMesg(level,text,workingFile);
    if (m_device != T_FILE) {
        fun(msg);
    }
    if (m_device != T_CONSILE)
    {
        outfile << msg;
        outfile.close();
    }
}

string XLogger::currTime()
{
    //????????????�Z???
    time_t timep;
    time(&timep); //?????1970?????????????????time_t?????timep
   //??ctime???????????????????????????Thu Feb 28 14:14:17 2019
    return string(ctime(&timep));
}

void XLogger::outPut(std::function<void (std::string&)> fun, string text, std::string filename,Level level, string workingFile)
{
    if (level < m_level) {
        return;
    }
    ofstream outfile;
    if (m_device != T_CONSILE) {
        outfile.open(filename, ios::out | ios::app);   // ???????????
    }
    string msg=getMesg(level,text,workingFile);
    if (m_device != T_FILE) {
        fun(msg);
    }
    if (m_device != T_CONSILE)
    {
        outfile << msg;
        outfile.close();
    }
}

void XLogger::outPut(std::function<void (std::string &&)> fun, string text, string filename, Level level, string workingFile)
{
    if (level < m_level) {
        return;
    }
    ofstream outfile;
    if (m_device != T_CONSILE) {
        outfile.open(filename, ios::out | ios::app);   // ???????????
    }
    string msg=getMesg(level,text,workingFile);
    if (m_device != T_CONSILE)
    {
        outfile << msg;
        outfile.close();
    }
    if (m_device != T_FILE) {
        fun(std::move(msg));
    }
}


std::string XLogger::levelToString(XLogger::Level level){

    switch (level)
    {
    case XLogger::L_DEBUG:
        return string("[DEBUG] ");
    case XLogger::L_INFO:
        return string("[INFO] ");
    case XLogger::L_WARNING:
        return string("[WARNING] ");
    case XLogger::L_ERROR:
        return string("[ERROR] ");
    case XLogger::L_CRITICAL:
        return string("[CRITICAL] ");
    default:
        break;
    }
    return string();
}


string XLogger::getMesg(Level level, string &text, string & workingFile){
    string msg=levelToString(level);
    msg += workingFile;
    msg += " ";
    string time = currTime();
    time.resize(currTime().size() - 1);
    msg += (std::move(time) + ": \"" + text + "\"\n");
    return msg;
}
